package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.auth.StpKit;
import com.cskaoyan.wordmemorize.common.entity.BaseDO;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.UserPrivilegeConverter;
import com.cskaoyan.wordmemorize.dao.entity.*;
import com.cskaoyan.wordmemorize.dao.mapper.*;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.UserVocAISituationDTO;
import com.cskaoyan.wordmemorize.dto.app.*;
import com.cskaoyan.wordmemorize.request.AIReviewReadCommand;
import com.cskaoyan.wordmemorize.request.PageRequest;
import com.cskaoyan.wordmemorize.request.UserFavoriteCommand;
import com.cskaoyan.wordmemorize.request.UserVocExampleSentenceCommand;
import com.cskaoyan.wordmemorize.service.UserPrivilegeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserPrivilegeServiceImpl extends ServiceImpl<UserFavoriteMapper, UserFavoriteDO> implements UserPrivilegeService {


    @Autowired
    UserPrivilegeConverter userPrivilegeConverter;

    @Autowired
    UserVocExampleSentenceMapper userVocExampleSentenceMapper;
    @Autowired
    VocBookMapper vocBookMapper;
    @Autowired
    UserFavoriteMapper userFavoriteMapper;
    @Autowired
    VocMeaningMapper vocMeaningMapper;
    @Autowired
    VocChapBookMapper vocChapBookMapper;
    @Autowired
    UserVocRevMapper userVocRevMapper;
    @Autowired
    UserNotRememberMapper userNotRememberMapper;
    @Autowired
    VocMapper vocMapper;

    // APP端获取词书进度
    @Override
    public UserVocBookStatisticsDTO getSelectedBookStatistics(Long userId, Long bookId) {
        // 在表voc_book中查询
        QueryWrapper<VocBookDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", bookId);
        VocBookDO vocBookDO = vocBookMapper.selectOne(queryWrapper);
        if (vocBookDO == null) {
            throw new BusinessException("词书不存在: " + bookId, 404);
        }
        // 1.词书单词总数
        Integer vocCount = vocBookDO.getVocCount();

        // 在表user_voc_rev中查询的所有单词
        QueryWrapper<UserVocRevDO> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_id", userId);
        List<UserVocRevDO> vocRevDOList = userVocRevMapper.selectList(queryWrapper1);

        // 该书已选的单词列表
        List<UserVocRevDO> selectedVocFromThisBookList = new ArrayList<>();
        Integer selectedCountFromThisBook = vocRevDOList.size();
        for (UserVocRevDO userVocRevDO : vocRevDOList) {
            Long vocId = userVocRevDO.getVocId();
            QueryWrapper<VocChapBookDO> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("voc_id", vocId);
            if (!vocChapBookMapper.exists(queryWrapper2)) {
                selectedVocFromThisBookList.add(userVocRevDO);
            }
        }
        // 2.未选单词数量
        Integer unSelectedCount = vocCount - selectedCountFromThisBook;
        // 3.熟悉的单词数量: 单词的复习间隔>= 365的单词
        Integer familiarCount = 0;
        // 4.不熟悉的单词指: 还处于学习状态(复习时间 = 今天)的单词
        Integer unFamiliarCount = 0;
        // 5.一般的单词:  已处于复习状态(复习时间 != 今天)，且复习时间间隔 < 365的单词
        Integer generalCount = 0;
        // 6.已选未学的单词数量(复习次数 = 0)
        Integer notStartedCount = 0;
        for (UserVocRevDO selectedVocFromThisBook : selectedVocFromThisBookList) {
            // 当前时间
            LocalDate now = LocalDate.now();
            if (selectedVocFromThisBook.getReviewInterval() != null && selectedVocFromThisBook.getNextReviewDate() == now) {
                // 如果单词的复习时间 = 今天,则不熟悉的单词数量+1
                unFamiliarCount++;
            } else if (selectedVocFromThisBook.getNextReviewDate() != null && selectedVocFromThisBook.getReviewInterval() >= 365) {
                // 如果单词的复习时间间隔 >= 365,则熟悉的单词数量+1
                familiarCount++;
            } else if (selectedVocFromThisBook.getNextReviewDate() != null && selectedVocFromThisBook.getNextReviewDate() != now && selectedVocFromThisBook.getReviewInterval() < 365) {
                // 如果单词的复习时间!= 今天,且复习时间间隔 < 365,则一般的单词数量+1
                generalCount++;
            } else if (selectedVocFromThisBook.getNextReviewDate() != null && selectedVocFromThisBook.getTotalReview() == 0 || selectedVocFromThisBook.getType() == 0) {
                // 如果单词的复习次数 = 0,则已选未学的单词数量+1
                notStartedCount++;
            }
        }
        // 封装成UserVocBookStatisticsDTO
        UserVocBookStatisticsDTO userVocBookStatisticsDTO = new UserVocBookStatisticsDTO();
        userVocBookStatisticsDTO.setUnFamiliar(unFamiliarCount);
        userVocBookStatisticsDTO.setGeneral(generalCount);
        userVocBookStatisticsDTO.setFamiliar(familiarCount);
        userVocBookStatisticsDTO.setNotStarted(notStartedCount);
        userVocBookStatisticsDTO.setTotal(vocCount);
        userVocBookStatisticsDTO.setUnSelected(unSelectedCount);
        return userVocBookStatisticsDTO;
    }

    // APP端批量添加收藏单词
    @Override
    @Transactional
    public void addFavoriteBulk(List<UserFavoriteCommand> userFavoriteCommand, Long userId) {
        //转换为DO集合并设置userId
        List<UserFavoriteDO> userFavoriteDOS = userPrivilegeConverter.userFavoriteDOs2DTOs(userFavoriteCommand);
        userFavoriteDOS.forEach(od -> od.setUserId(userId));
        userFavoriteDOS.forEach(od -> od.setSelected(1));

        //  提取所有单词ID
        List<Long> vocIds = new ArrayList<>();
        for (UserFavoriteCommand favoriteCommand : userFavoriteCommand) {
            String vocId = favoriteCommand.getVocId();
            vocIds.add(Long.valueOf(vocId));
        }
         //单词 id map集合
        Map<Long, String> contentMap = vocMapper.selectBatchIds(vocIds).stream()
                .collect(Collectors.toMap(VocDO::getId, VocDO::getContent));

        // 设置单词内容到收藏记录
        userFavoriteDOS.forEach(fav ->
                fav.setVocContent(contentMap.getOrDefault(fav.getVocId(), ""))
        );

        this.saveBatch(userFavoriteDOS);

    }

    // APP端单个添加收藏单词
    @Override
    @Transactional
    public void addFavorite(UserFavoriteCommand userFavoriteCommand, Long userId) {
        UserFavoriteDO userFavoriteDO = userPrivilegeConverter.userFavoriteCommand2DO(userFavoriteCommand);
        userFavoriteDO.setUserId(StpKit.USER.getLoginIdAsLong());
        userFavoriteMapper.insert(userFavoriteDO);
    }

    // APP端取消收藏单词
    @Override
    @Transactional
    public void cancelFavorite(List<Long> ids, Long userId) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        // 创建删除条件
        LambdaQueryWrapper<UserFavoriteDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(UserFavoriteDO::getVocId, ids)
                .eq(UserFavoriteDO::getUserId, userId); // 确保只删除当前用户的收藏

        // 执行删除
        userFavoriteMapper.delete(queryWrapper);
    }

    // APP端获取单词收藏列表
    @Override
    @Transactional
    public PageDTO<UserFavoriteDTO> getUserFavoriteList(PageRequest pageRequest, Long userId) {
        //分页查询
        Page<UserFavoriteDO> page =
                new Page<>(pageRequest.getPageNum(), pageRequest.getCount());
        //分页查询条件
        LambdaQueryWrapper<UserFavoriteDO> queryWrapper = new LambdaQueryWrapper<>();
        //查询用户收藏列表
        queryWrapper.eq(UserFavoriteDO::getUserId,userId);
        Page<UserFavoriteDO> favoritePage = userFavoriteMapper.selectPage(page, queryWrapper);

        //获取分页中每一条记录,interpretations字段为空
        List<UserFavoriteDO> records = favoritePage.getRecords();
        long total = favoritePage.getTotal();//总记录数 单词总数
        //interpretations字段查询voc_meaning表
        for (UserFavoriteDO record : records) {
            Long vocId = record.getVocId();
            LambdaQueryWrapper<VocMeaningDO> meaningDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
            meaningDOLambdaQueryWrapper.eq(VocMeaningDO::getVocId,vocId);
            List<VocMeaningDO> vocMeaningDOS = vocMeaningMapper.selectList(meaningDOLambdaQueryWrapper);
            record.setInterpretations(vocMeaningDOS);
        }
        //查询user_voc_rev表 判断单词是否已选择复习
        for (UserFavoriteDO record : records) {
            Long vocId = record.getVocId();
            LambdaQueryWrapper<UserVocRevDO> userVocRevDOLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userVocRevDOLambdaQueryWrapper.eq(UserVocRevDO::getVocId,vocId)
                    .eq(UserVocRevDO::getUserId,userId);
            //如果user_voc_rev表中有该单词,则selected字段为1
            if (userVocRevMapper.exists(userVocRevDOLambdaQueryWrapper)){
                record.setSelected(1);
            }else {
                record.setSelected(0);
            }
        }
        //DO->DTO
        PageDTO<UserFavoriteDTO> userFavoriteDTOPageDTO = userPrivilegeConverter.userFavoriteDOPage2PageDTO(records, total);
        return userFavoriteDTOPageDTO;

    }

    // APP端添加用户自建例句
    @Override
    @Transactional
    public void addUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {
        UserVocExampleSentenceDO userVocExampleSentenceDO =
                userPrivilegeConverter.userVocExampleSentenceCommand2DO(command);
        userVocExampleSentenceDO.setUserId(StpKit.USER.getLoginIdAsLong());
        userVocExampleSentenceMapper.insert(userVocExampleSentenceDO);
    }

    // APP端获取用户自建例句
    @Override
    @Transactional
    public PageDTO<DisplayUserVocSentenceDTO> getUserVocSentence(PageRequest pageRequest, Long userId) {
        // 分页查询
        Page page = new Page(pageRequest.getPageNum(), pageRequest.getCount());
        QueryWrapper<UserVocExampleSentenceDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        userVocExampleSentenceMapper.selectPage(page, queryWrapper);
        // 获取分页中的每一条记录
        List<UserVocExampleSentenceDO> userVocExampleSentenceDOList = page.getRecords();

        // 总记录数
        Long total = page.getTotal();

        // 将userVocExampleSentenceDOList按照vocId分组
        Map<Long, List<UserVocExampleSentenceDO>> sentencesOfVoc
                = userVocExampleSentenceDOList.stream().collect(Collectors.groupingBy(UserVocExampleSentenceDO::getVocId));


        List<DisplayUserVocSentenceDTO> displayUserVocSentenceDTOS = sentencesOfVoc.entrySet().stream().map(entry -> {
            Long vocId = entry.getKey();
            List<UserVocExampleSentenceDO> sentences = entry.getValue();
            String vocContent = sentences.get(0).getVocContent();

            DisplayUserVocSentenceDTO displayUserVocSentenceDTO = new DisplayUserVocSentenceDTO();
            displayUserVocSentenceDTO.setUserId(userId.toString());
            displayUserVocSentenceDTO.setVocId(vocId.toString());
            displayUserVocSentenceDTO.setVocContent(vocContent);
            List<UserVocSentenceDTO> userVocSentenceDTOS = userPrivilegeConverter.userVocSentenceDOs2DTOs(sentences);
            displayUserVocSentenceDTO.setSentences(userVocSentenceDTOS);
            return displayUserVocSentenceDTO;
        }).collect(Collectors.toList());

        // 封装成PageDTO
        PageDTO<DisplayUserVocSentenceDTO> pageDTO
                = userPrivilegeConverter.displayUserVocSentenceDTOList2PageDTO(displayUserVocSentenceDTOS, total);

        return pageDTO;
    }

    // APP端更新用户自建例句
    @Override
    @Transactional
    public void updateUserVocSentence(UserVocExampleSentenceCommand command, Long userId) {
        // 1. 查询用户对该单词的自建例句
        LambdaQueryWrapper<UserVocExampleSentenceDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserVocExampleSentenceDO::getUserId, userId)
                .eq(UserVocExampleSentenceDO::getVocId, command.getVocId());

        UserVocExampleSentenceDO existingDO = userVocExampleSentenceMapper.selectOne(queryWrapper);

        // 2. 验证记录存在
        if (existingDO == null) {
            throw new BusinessException("没有找到可更新的例句",500);
        }

        // 3. 更新记录
        LambdaUpdateWrapper<UserVocExampleSentenceDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserVocExampleSentenceDO::getId, existingDO.getId())
                .set(UserVocExampleSentenceDO::getSentence, command.getSentence())
                .set(UserVocExampleSentenceDO::getMeaning, command.getMeaning());

        userVocExampleSentenceMapper.update(null, updateWrapper);
    }

    // APP端删除用户自建例句
    @Override
    @Transactional
    public void deleteUserVocSentence(Long id) {
        userVocExampleSentenceMapper.deleteById(id);
    }

    // APP端表示不想背
    @Override
    @Transactional
    public void notRemember(Long vocId, Long userId) {

            // 在user_not_remember表中添加的数据
            UserNotRememberDO userNotRememberDO = new UserNotRememberDO();
            userNotRememberDO.setUserId(userId);
            userNotRememberDO.setVocId(vocId);
            boolean ret1 = userNotRememberMapper.insertOrUpdate(userNotRememberDO);
            // 如果user_voc_rev表中有这个数据，则删除
            QueryWrapper<UserVocRevDO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("voc_id", vocId)
                    .eq("user_id", userId);
            if (userVocRevMapper.exists(queryWrapper)) {
                userVocRevMapper.delete(queryWrapper);
            }

    }

    // APP端取消标识不想背
    @Override
    @Transactional
    public void cancelNotRemember(Long vocId, Long userId) {
            // 在user_not_remember表中的数据is_delete设置为1
            UpdateWrapper<UserNotRememberDO> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("user_id", userId)
                    .eq("voc_id", vocId);
            int ret = userNotRememberMapper.delete(updateWrapper);
            if (ret == 0) {
                throw new BusinessException("请求失败", 500);
            }
    }

    // APP端获取AI阅读模式以及选项
    @Override
    public List<UserVocAISituationDTO> getAIReviewReadOptions() {
        return null;
    }

    // APP端获取用户剩余免费AI阅读次数
    @Override
    public Integer getUserVocAIReadRemainFreeCount(Long userId) {
        return null;
    }

    // APP端获取AI阅读结果
    @Override
    public List<AIReviewReadDTO> getAIReviewReadContent(AIReviewReadCommand command, Long userId) {
        return null;
    }


}
